﻿using System;
using System.Collections;
using System.Web;
using System.Security.Permissions;
using System.Web.UI;
using System.Collections.Specialized;


namespace MCCJ
{
     /// <summary>支持 <see cref="T:System.Web.UI.WebControls.ObjectDataSource" /> 控件并提供一个接口，使数据绑定控件可以对业务对象和数据对象执行数据操作。</summary>
 [AspNetHostingPermission(SecurityAction.LinkDemand, Level=AspNetHostingPermissionLevel.Minimal), AspNetHostingPermission(SecurityAction.InheritanceDemand, Level=AspNetHostingPermissionLevel.Minimal)]
    public class ObjectDataSourceView : System.Web.UI.WebControls.ObjectDataSourceView
    {
     private HttpContext _context;
     private ObjectDataSource _owner;

        ///<summary>初始化 <see cref="T:System.Web.UI.WebControls.ObjectDataSourceView" /> 类的新实例。</summary>
        ///<param name="owner">与 <see cref="T:System.Web.UI.WebControls.ObjectDataSourceView" /> 关联的 <see cref="T:System.Web.UI.WebControls.ObjectDataSourceView" />。</param>
        ///<param name="name">数据源视图的唯一名称（在拥有它的数据源控件的范围内）。</param>
        ///<param name="context">当前的 <see cref="T:System.Web.HttpContext" />。</param>
        public ObjectDataSourceView(ObjectDataSource owner, string name, HttpContext context)
            : base(owner, name,context)
     {
         this._owner = owner;
         this._context = context;

        }

     
        //protected override int ExecuteDelete(IDictionary keys, IDictionary oldValues)
        //{
        //    ObjectDataSourceMethod method;
        //    if (!this.CanDelete)
        //    {
        //        throw new NotSupportedException(string.Format("ObjectDataSourceView_DeleteNotSupported", new object[] { this._owner.ID }));
        //    }
        //    Type type = this.GetType(this.TypeName);
        //    Type dataObjectType = this.TryGetDataObjectType();
        //    if (dataObjectType != null)
        //    {
        //        IDictionary destination = new OrderedDictionary(StringComparer.OrdinalIgnoreCase);
        //        MergeDictionaries(this.DeleteParameters, keys, destination);
        //        if (this.ConflictDetection == ConflictOptions.CompareAllValues)
        //        {
        //            if (oldValues == null)
        //            {
        //                throw new InvalidOperationException(string.Format("ObjectDataSourceView_Pessimistic", new object[] { string.Format("DataSourceView_delete"), this._owner.ID, "oldValues" }));
        //            }
        //            MergeDictionaries(this.DeleteParameters, oldValues, destination);
        //        }
        //        object oldDataObject = this.BuildDataObject(dataObjectType, destination);
        //        method = this.GetResolvedMethodData(type, this.DeleteMethod, dataObjectType, oldDataObject, null, DataSourceOperation.Delete);
        //        ObjectDataSourceMethodEventArgs e = new ObjectDataSourceMethodEventArgs(method.Parameters);
        //        this.OnDeleting(e);
        //        if (e.Cancel)
        //        {
        //            return 0;
        //        }
        //    }
        //    else
        //    {
        //        IOrderedDictionary dictionary2 = new OrderedDictionary(StringComparer.OrdinalIgnoreCase);
        //        string oldValuesParameterFormatString = this.OldValuesParameterFormatString;
        //        MergeDictionaries(this.DeleteParameters, this.DeleteParameters.GetValues(this._context, this._owner), dictionary2);
        //        MergeDictionaries(this.DeleteParameters, keys, dictionary2, oldValuesParameterFormatString);
        //        if (this.ConflictDetection == ConflictOptions.CompareAllValues)
        //        {
        //            if (oldValues == null)
        //            {
        //                throw new InvalidOperationException(string.Format("ObjectDataSourceView_Pessimistic", new object[] { string.Format("DataSourceView_delete"), this._owner.ID, "oldValues" }));
        //            }
        //            MergeDictionaries(this.DeleteParameters, oldValues, dictionary2, oldValuesParameterFormatString);
        //        }
        //        ObjectDataSourceMethodEventArgs args2 = new ObjectDataSourceMethodEventArgs(dictionary2);
        //        this.OnDeleting(args2);
        //        if (args2.Cancel)
        //        {
        //            return 0;
        //        }
        //        method = this.GetResolvedMethodData(type, this.DeleteMethod, dictionary2, DataSourceOperation.Delete);
        //    }
        //    ObjectDataSourceResult result = this.InvokeMethod(method);
        //    if (this._owner.Cache.Enabled)
        //    {
        //        this._owner.InvalidateCacheEntry();
        //    }
        //    this.OnDataSourceViewChanged(EventArgs.Empty);
        //    return result.AffectedRows;
        //}

        protected  override IEnumerable ExecuteSelect(DataSourceSelectArguments arguments)
        {
            if (this.SelectMethod.Length == 0)
            {
                throw new InvalidOperationException(string.Format("ObjectDataSourceView_SelectNotSupported", new object[] { this._owner.ID }));
            }
            if (this.CanSort)
            {
                arguments.AddSupportedCapabilities(DataSourceCapabilities.Sort);
            }
            if (this.CanPage)
            {
                arguments.AddSupportedCapabilities(DataSourceCapabilities.Page);
            }
            if (this.CanRetrieveTotalRowCount)
            {
                arguments.AddSupportedCapabilities(DataSourceCapabilities.RetrieveTotalRowCount);
            }
            arguments.RaiseUnsupportedCapabilitiesError(this);
            IOrderedDictionary parameters = new OrderedDictionary(StringComparer.OrdinalIgnoreCase);
            foreach (DictionaryEntry entry in this.SelectParameters.GetValues(this._context, this._owner))
            {
                parameters[entry.Key] = entry.Value;
            }
            //bool enabled = this._owner.Cache.Enabled;
            //if (enabled)
            //{
            //    object dataObject = this._owner.LoadDataFromCache(arguments.StartRowIndex, arguments.MaximumRows);
            //    if (dataObject != null)
            //    {
            //        DataView view = dataObject as DataView;
            //        if (view != null)
            //        {
            //            if (arguments.RetrieveTotalRowCount && (this.SelectCountMethod.Length == 0))
            //            {
            //                arguments.TotalRowCount = view.Count;
            //            }
            //            if (this.FilterExpression.Length > 0)
            //            {
            //                throw new NotSupportedException(string.Format("ObjectDataSourceView_FilterNotSupported", new object[] { this._owner.ID }));
            //            }
            //            if (string.IsNullOrEmpty(arguments.SortExpression))
            //            {
            //                return view;
            //            }
            //        }
            //        else
            //        {
            //            DataTable table = FilteredDataSetHelper.GetDataTable(this._owner, dataObject);
            //            if (table != null)
            //            {
            //                this.ProcessPagingData(arguments, parameters);
            //                return this.CreateFilteredDataView(table, arguments.SortExpression, this.FilterExpression);
            //            }
            //            IEnumerable enumerable = this.CreateEnumerableData(dataObject, arguments);
            //            this.ProcessPagingData(arguments, parameters);
            //            return enumerable;
            //        }
            //    }
            //}
            System.Web.UI.WebControls.ObjectDataSourceSelectingEventArgs e = new System.Web.UI.WebControls.ObjectDataSourceSelectingEventArgs(parameters, arguments, false);
            this.OnSelecting(e);
            if (e.Cancel)
            {
                return null;
            }
            OrderedDictionary mergedParameters = new OrderedDictionary(parameters.Count);
            foreach (DictionaryEntry entry2 in parameters)
            {
                mergedParameters.Add(entry2.Key, entry2.Value);
            }
            string sortParameterName = this.SortParameterName;
            if (sortParameterName.Length > 0)
            {
                parameters[sortParameterName] = arguments.SortExpression;
                arguments.SortExpression = string.Empty;
            }
            if (this.EnablePaging)
            {
                string maximumRowsParameterName = this.MaximumRowsParameterName;
                string startRowIndexParameterName = this.StartRowIndexParameterName;
                if (string.IsNullOrEmpty(maximumRowsParameterName) || string.IsNullOrEmpty(startRowIndexParameterName))
                {
                    throw new InvalidOperationException(string.Format("ObjectDataSourceView_MissingPagingSettings", new object[] { this._owner.ID }));
                }
                IDictionary source = new OrderedDictionary(StringComparer.OrdinalIgnoreCase);
                source[maximumRowsParameterName] = arguments.MaximumRows;
                source[startRowIndexParameterName] = arguments.StartRowIndex;
                MergeDictionaries(this.SelectParameters, source, parameters);
            }
            Type type = this.GetType(this.TypeName);
            object instance = null;
            ObjectDataSourceResult result = null;
            try
            {
                ObjectDataSourceMethod method = this.GetResolvedMethodData(type, this.SelectMethod, parameters, DataSourceOperation.Select);
                result = this.InvokeMethod(method, false, ref instance);
                if (result.ReturnValue == null)
                {
                    return null;
                }
                if (arguments.RetrieveTotalRowCount && (this.SelectCountMethod.Length > 0))
                {
                    int totalRowCount = -1;
                    if (enabled)
                    {
                        totalRowCount = this._owner.LoadTotalRowCountFromCache();
                        if (totalRowCount >= 0)
                        {
                            arguments.TotalRowCount = totalRowCount;
                        }
                    }
                    if (totalRowCount < 0)
                    {
                        totalRowCount = this.QueryTotalRowCount(mergedParameters, arguments, true, ref instance);
                        arguments.TotalRowCount = totalRowCount;
                        if (enabled)
                        {
                            this._owner.SaveTotalRowCountToCache(totalRowCount);
                        }
                    }
                }
            }
            finally
            {
                if (instance != null)
                {
                    this.ReleaseInstance(instance);
                }
            }
            DataView returnValue = result.ReturnValue as DataView;
            if (returnValue != null)
            {
                if (arguments.RetrieveTotalRowCount && (this.SelectCountMethod.Length == 0))
                {
                    arguments.TotalRowCount = returnValue.Count;
                }
                if (this.FilterExpression.Length > 0)
                {
                    throw new NotSupportedException(string.Format("ObjectDataSourceView_FilterNotSupported", new object[] { this._owner.ID }));
                }
                if (!string.IsNullOrEmpty(arguments.SortExpression))
                {
                    if (enabled)
                    {
                        throw new NotSupportedException(string.Format("ObjectDataSourceView_CacheNotSupportedOnSortedDataView", new object[] { this._owner.ID }));
                    }
                    returnValue.Sort = arguments.SortExpression;
                }
                if (enabled)
                {
                    this.SaveDataAndRowCountToCache(arguments, result.ReturnValue);
                }
                return returnValue;
            }
            DataTable dataTable = FilteredDataSetHelper.GetDataTable(this._owner, result.ReturnValue);
            if (dataTable != null)
            {
                if (arguments.RetrieveTotalRowCount && (this.SelectCountMethod.Length == 0))
                {
                    arguments.TotalRowCount = dataTable.Rows.Count;
                }
                if (enabled)
                {
                    this.SaveDataAndRowCountToCache(arguments, result.ReturnValue);
                }
                return this.CreateFilteredDataView(dataTable, arguments.SortExpression, this.FilterExpression);
            }
            IEnumerable data = this.CreateEnumerableData(result.ReturnValue, arguments);
            if (enabled)
            {
                if (data is IDataReader)
                {
                    throw new NotSupportedException(string.Format("ObjectDataSourceView_CacheNotSupportedOnIDataReader", new object[] { this._owner.ID }));
                }
                this.SaveDataAndRowCountToCache(arguments, data);
            }
            return data;
        }






     //#region IStateManager 成员
     ///// <summary>获取一个值，该值指示 <see cref="T:System.Web.UI.WebControls.ObjectDataSourceView" /> 对象是否保存它的视图状态更改。</summary>
     ///// <returns>如果数据源视图被标记为保存其状态，则为 true；否则为 false。</returns>
     //public bool IsTrackingViewState
     //{
     //    get
     //    {
     //        return this._tracking;
     //    }
     //}
     ///// <summary>还原数据源视图的以前保存的视图状态。</summary>
     ///// <param name="savedState">一个对象，表示要还原的 <see cref="T:System.Web.UI.WebControls.ObjectDataSourceView" /> 状态。</param>
     //public virtual void LoadViewState(object savedState)
     //{
     //    if (savedState != null)
     //    {
     //        Pair pair = (Pair)savedState;
     //        if (pair.First != null)
     //        {
     //            ((IStateManager)this.SelectParameters).LoadViewState(pair.First);
     //        }
     //        if (pair.Second != null)
     //        {
     //            ((IStateManager)this.FilterParameters).LoadViewState(pair.Second);
     //        }
     //    }

     //}
     ///// <summary>保存自页回发到服务器后，<see cref="T:System.Web.UI.WebControls.ObjectDataSourceView" /> 对象的视图状态更改。</summary>
     ///// <returns>包含 <see cref="T:System.Web.UI.WebControls.ObjectDataSourceView" /> 视图状态更改的对象；否则，如果没有与对象关联的视图状态，则为 null。</returns>
     //public virtual object SaveViewState()
     //{
     //    Pair pair = new Pair();
     //    pair.First = (this._selectParameters != null) ? ((IStateManager)this._selectParameters).SaveViewState() : null;
     //    pair.Second = (this._filterParameters != null) ? ((IStateManager)this._filterParameters).SaveViewState() : null;
     //    if ((pair.First == null) && (pair.Second == null))
     //    {
     //        return null;
     //    }
     //    return pair;

     //}
     ///// <summary>使 <see cref="T:System.Web.UI.WebControls.ObjectDataSourceView" /> 对象跟踪其视图状态更改，以便这些更改可以存储在控件的 <see cref="P:System.Web.UI.Control.ViewState" /> 对象中并在同一页的不同请求间保留。</summary>
     //public virtual void TrackViewState()
     //{
     //    this._tracking = true;
     //    if (this._selectParameters != null)
     //    {
     //        ((IStateManager)this._selectParameters).TrackViewState();
     //    }
     //    if (this._filterParameters != null)
     //    {
     //        ((IStateManager)this._filterParameters).TrackViewState();
     //    }

     //}
     //#endregion

























        //System.Type typeName = null;
        //MccjDataSource owner = null;
        //public ObjectDataSourceView(MccjDataSource owner, string name):base(owner, name)
        //{
        //    this.owner = owner;
        //    foreach (System.Reflection.Assembly item in System.AppDomain.CurrentDomain.GetAssemblies())
        //    {
        //        if (typeName != null) { break; }
        //        typeName = item.GetType(owner.TypeName,false, true);
        //    }
        //}
        ////public MccjDataSourceView(IDataSource owner, string name)
        ////    : base(owner, DefaultViewName)
        ////{

        ////}

        //// The data source view is named. However, the CsvDataSource
        //// only supports one view, so the name is ignored, and the
        //// default name used instead.
        ////public static string DefaultViewName = "";

        ////// The location of the .csv file.
        ////private string sourceFile = String.Empty;
        ////internal string SourceFile
        ////{
        ////    get
        ////    {
        ////        return sourceFile;
        ////    }
        ////    set
        ////    {
        ////        // Use MapPath when the SourceFile is set, so that files local to the
        ////        // current directory can be easily used.
        ////        string mappedFileName = HttpContext.Current.Server.MapPath(value);
        ////        sourceFile = mappedFileName;
        ////    }
        ////}

        ////// Do not add the column names as a data row. Infer columns if the CSV file does
        ////// not include column names.
        ////private bool columns = false;
        ////internal bool IncludesColumnNames
        ////{
        ////    get
        ////    {
        ////        return columns;
        ////    }
        ////    set
        ////    {
        ////        columns = value;
        ////    }
        ////}

        ////// Get data from the underlying data source.
        ////// Build and return a DataView, regardless of mode.
        //protected override System.Collections.IEnumerable ExecuteSelect(DataSourceSelectArguments arguments)
        //{
        //   // 

        //    object[] obj = new object[] { owner.PageSize, owner.PageIndex, owner.strWhere, owner.strOrder, 0, 0 };
        //    System.Reflection.MethodInfo mf = typeName.GetMethod(owner.SelectMethod, System.Reflection.BindingFlags.InvokeMethod | System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.Static, null, new System.Type[] { typeof(int), typeof(int), typeof(string), typeof(string), System.Type.GetType("System.Int32&"), System.Type.GetType("System.Int32&") }, null);
        //    object o = mf.Invoke(null, obj);
        //    return o as System.Collections.IEnumerable;

            
        //    // System.Collections.IEnumerable dataList = null;
        //    ////    // Open the .csv file.
        //    ////    if (File.Exists(this.SourceFile))
        //    ////    {
        //    // System.Data.DataTable data = new System.Data.DataTable();
        //    // data.Columns.Add("dddd");
        //    // data.Rows.Add(new string[] { "ssss"});
        //    ////        // Open the file to read from.
        //    ////        using (StreamReader sr = File.OpenText(this.SourceFile))
        //    ////        {
        //    ////            // Parse the line
        //    ////            string s = "";
        //    ////            string[] dataValues;
        //    ////            DataColumn col;

        //    ////            // Do the following to add schema.
        //    ////            dataValues = sr.ReadLine().Split(',');
        //    ////            // For each token in the comma-delimited string, add a column
        //    ////            // to the DataTable schema.
        //    ////            foreach (string token in dataValues)
        //    ////            {
        //    ////                col = new DataColumn(token, typeof(string));
        //    ////                data.Columns.Add(col);
        //    ////            }

        //    ////            // Do not add the first row as data if the CSV file includes column names.
        //    ////            if (!IncludesColumnNames)
        //    ////                data.Rows.Add(CopyRowData(dataValues, data.NewRow()));

        //    ////            // Do the following to add data.
        //    ////            while ((s = sr.ReadLine()) != null)
        //    ////            {
        //    ////                dataValues = s.Split(',');
        //    ////                data.Rows.Add(CopyRowData(dataValues, data.NewRow()));
        //    ////            }
        //    ////        }
        //    ////        data.AcceptChanges();
        //    // System.Data.DataView dataView = new System.Data.DataView(data);
        //    ////        if (selectArgs.SortExpression != String.Empty)
        //    ////        {
        //    ////            dataView.Sort = selectArgs.SortExpression;
        //    ////        }
        //    // dataList = dataView;
        //    ////    }
        //    ////    else
        //    ////    {
        //    ////        throw new System.Configuration.ConfigurationErrorsException("File not found, " + this.SourceFile);
        //    ////    }

        //    ////    if (null == dataList)
        //    ////    {
        //    ////        throw new InvalidOperationException("No data loaded from data source.");
        //    ////    }

        //    //    return dataList;
        //}

        ////private DataRow CopyRowData(string[] source, DataRow target)
        ////{
        ////    try
        ////    {
        ////        for (int i = 0; i < source.Length; i++)
        ////        {
        ////            target[i] = source[i];
        ////        }
        ////    }
        ////    catch (System.IndexOutOfRangeException)
        ////    {
        ////        // There are more columns in this row than
        ////        // the original schema allows.  Stop copying
        ////        // and return the DataRow.
        ////        return target;
        ////    }
        ////    return target;
        ////}
        ////// The CsvDataSourceView does not currently
        ////// permit deletion. You can modify or extend
        ////// this sample to do so.
        ////public override bool CanDelete
        ////{
        ////    get
        ////    {
        ////        return false;
        ////    }
        ////}
        //protected override int ExecuteDelete(System.Collections.IDictionary keys, System.Collections.IDictionary oldValues)
        //{
        //    foreach (System.Collections.DictionaryEntry item in keys)
        //    {

        //    }
        //    return 0;
        //    //return base.ExecuteDelete(keys, oldValues);
        //}

        ////// The CsvDataSourceView does not currently
        ////// permit insertion of a new record. You can
        ////// modify or extend this sample to do so.
        ////public override bool CanInsert
        ////{
        ////    get
        ////    {
        ////        return false;
        ////    }
        ////}
        //protected override int ExecuteInsert(System.Collections.IDictionary values)
        //{
        //    return base.ExecuteInsert(values);
        //}
       
        ////// The CsvDataSourceView does not currently
        ////// permit update operations. You can modify or
        ////// extend this sample to do so.
        ////public override bool CanUpdate
        ////{
        ////    get
        ////    {
        ////        return false;
        ////    }
        ////}

        //protected override int ExecuteUpdate(System.Collections.IDictionary keys, System.Collections.IDictionary values, System.Collections.IDictionary oldValues)
        //{
        //    return 1;
        //}





     
    }

}